/*
 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
 * http://www.gnu.org/licenses/lgpl-3.0.html
 */

#ifndef EDITORBASE_H
#define EDITORBASE_H

#include "prep.h"

#include <wx/hashmap.h>
#include <wx/frame.h>
#include <wx/panel.h>
#include "globals.h"
#include "settings.h"
#include "cbexception.h"

class wxMenu;
class EditorBase;
struct EditorBaseInternalData;
class cbDebuggerPlugin;

WX_DECLARE_HASH_MAP(int, EditorBase*, wxIntegerHash, wxIntegerEqual, SwitchToMap);

/**
 * 实现功能: 所有"编辑器"都应继承的基类.
 * 注释: 这个类从wxPanel派生,因此它还提供了所有wxPanel方法...
*/
class DLLIMPORT EditorBase : public wxPanel
{
    DECLARE_EVENT_TABLE()
    public:
        EditorBase(wxWindow* parent, const wxString& filename);
        virtual ~EditorBase();
        /*别用这个.如果你这样做,它会抛出一个异常.*/
        void operator=(cb_optional const EditorBase& rhs){ cbThrow(wxT("无法分配一个EditorBase*指针 !!!")); }
        /**
         * 实现功能: 获取编辑器的文件名(如果适用).
         * 返回值:  编辑的文件名.
         * */
        virtual const wxString& GetFilename() const { return m_Filename; }

        /**
          * 实现功能: 设置编辑器的文件名.
          * 参数说明: filename 要设置的文件名.
          */
        virtual void SetFilename(const wxString& filename){ m_Filename = filename; }

        /**
          *
         * 实现功能: 返回编辑器的简称
          * 这是编辑器选项卡上显示的名称...
          * 同义词是GetTitle().
          *
          */
        virtual const wxString& GetShortName() const { return m_Shortname; }

        /**
         * 实现功能: 是修改过的吗?
          * 返回值:  如果修改了编辑器,则为true否则为false.
          * 注释: 此函数应始终由实现重写,因为EditorBase中的默认实现始终返回false.
          */
        virtual bool GetModified() const { return false; }

        /**
         * 实现功能: 设置修改状态.
          * 参数说明: modified 如果为真则标记为已修改.如果为false则标记为clean(未修改).
          */
        virtual void SetModified(bool /*modified*/ = true) {}

        /**
         * 实现功能: 编辑器标题.
          * 返回值:  编辑器标题.
          *
          */
        virtual const wxString& GetTitle();

        /**
         * 实现功能: 设置标记器标题.
         * 参数说明: newTitle 设置的新标题.
          */
        virtual void SetTitle(const wxString& newTitle);

        /**
         * 实现功能: 激活这个标记器.
         * 使此编辑器被激活,即显示在最前面.
          */
        virtual void Activate();

        /**
         * 实现功能: 这个可以关闭(销毁)吗?
         * 这在内部使用,并询问编辑器是否可以安全地关闭它(即它没有被修改).
         * 返回值:  True 如果这个编辑器可以关闭.
          */
        virtual bool QueryClose();

        /**
         * 实现功能: 关闭这个编辑器.
         * 默认实现关闭(销毁)编辑器并返回true.
         * 返回值:  True 如果编辑器成功关闭
          */
        virtual bool Close();

        /**
         * 实现功能: 保存内容.
         * 保存编辑器的内容,默认实现不执行任何操作并返回true
         * 返回值:  成功时为真,否则为假.
        */
        virtual bool Save() { return true; }

        /**
         * 实现功能: 将编辑器内容保存(另外文件类型)在其他文件名下.默认实现不执行任何操作并返回true.
         * 返回值:  成功时为真,否则为假.
         * */
        virtual bool SaveAs() { return true; }

        /**
         * 实现功能: 这是一个内置的编辑器吗.
         * 查询这是否是一个内置编辑器(也称为cbEditor).
         * 返回值:  如果是cbEditor,则为True否则为false.
          */
        virtual bool IsBuiltinEditor() const;

        /**
         * 实现功能: 除此之外还有其他编辑吗?
         * 返回值:  如果有更多的编辑器打开,则为True否则为false.
          */
        virtual bool ThereAreOthers() const;

        /**
         * 实现功能: 显示上下文菜单.
         * 显示编辑器的上下文菜单.如果用户在编辑器区域中单击鼠标右键,则会自动调用此命令.
         * 参数说明: position 弹出上下文菜单的位置.
         * 参数说明: type 模块的类型.
          */
        virtual void DisplayContextMenu(const wxPoint& position, ModuleType type = mtUnknown);

        /**
         * 这种编辑器应该在"打开的文件"树中可见吗?
         * 很少有编辑器在"打开的文件"树中不可见的情况.
         * 其中一个例子是"从这里开始"页面...
         * 返回值:  如果它在"打开的文件"树中可见则为True,如果不可见则为false.
          */
        virtual bool VisibleToTree() const { return true; }

        /**
         * 在指定行移动插入符号.
         * 参数说明: line 要将插入符号移动到的行.
         * 参数说明: centerOnScreen 如果为true则相关行将位于编辑器区域的中心(如果可能).如果是错误的,它将被显示出来.
          */
        virtual void GotoLine(int /*line*/, bool /*centerOnScreen*/ = true){}
        /*撤消更改*/
        virtual void Undo(){}
         /*重做更改.*/
        virtual void Redo(){}
        /*清除撤消(和变更栏)历史记录*/
        virtual void ClearHistory(){}
        /*转到下一个更改行*/
        virtual void GotoNextChanged(){}
        /*转到上一个更改行*/
        virtual void GotoPreviousChanged(){}
        /*启用或禁用变更栏*/
        virtual void SetChangeCollection(cb_optional bool collectChange){}
        /*将选定的文本/对象剪切到剪贴板.*/
        virtual void Cut(){}
        /*将所选文本/对象复制到剪贴板.*/
        virtual void Copy(){}
        /*从剪贴板粘贴选定的文本/对象.*/
        virtual void Paste(){}
        /**
          * 有什么要撤销的吗?有可撤销的操作记录吗?
          * 返回值: 如果有什么东西要撤销那就是真的,如果没有那就是假的.
          */
        virtual bool CanUndo() const { return false; }

        /**
         * 有可重做的操作记录吗？
         * 返回值: 如果有什么东西可以重做那就是真的,如果没有那就是假的.
         */
        virtual bool CanRedo() const { return false; }

        /**
         * 有选择的编辑内容吗?
         * 返回值:  如果选择了文本/对象则为True,否则为false.
          */
        virtual bool HasSelection() const { return false; }

        /**
         * 有东西可以粘贴吗？
         * 返回值:  如果有粘帖内容则为真,否则为假.
          */
        virtual bool CanPaste() const { return false; }

        /**
         * 编辑器只读吗?
         * 返回值: 如果编辑器只读则为真,否则为假.
          */
        virtual bool IsReadOnly() const { return false; }

        /**
         * 设置编辑器只读.
         * 参数说明: 只读如果为真,则标记为只读.如果为false,则标记为读写.
          */
        virtual void SetReadOnly(bool /*readonly*/ = true) {}

        /**
         * 编辑器能全部选择吗?
         * 返回值:  如果编辑器可以选择所有内容则为True,否则为false.
          */
        virtual bool CanSelectAll() const { return false; }

        /*在编辑器内全选*/
        virtual void SelectAll() { return; }

        /**
         * 是否有上下文(右键单击)菜单打开.
         * 返回值: 如果上下文菜单打开则为True,否则为false.
          */
        virtual bool IsContextMenuOpened() const;
    protected:
        /**
         * 初始化文件名数据.
         * 参数说明: filename 用于初始化的编辑器文件名.
          */
        virtual void InitFilename(const wxString& filename);

        /**
         * 创建上下文子菜单.有关详细信息,请参见cbEditor代码.
         * 参数说明: id 事件处理程序的ID.
         * 返回值:  创建的子菜单,如果不适用,则为空.
          */
        /*对于上下文菜单*/
        virtual wxMenu* CreateContextSubMenu(long id);
        /**
         * 在创建插件菜单项之前和之后创建上下文菜单项.
         * 参数说明: popup 弹出菜单.
         * 参数说明: type 模块的类型.
         * 参数说明: pluginsdone 如果已创建插件菜单则为True,否则为false.
          */
        virtual void AddToContextMenu(cb_optional wxMenu* popup, cb_optional ModuleType type, cb_optional bool pluginsdone) {}

        /**
         * 在要求保存文件时创建唯一的文件名.
         * 返回值:  唯一的文件名建议.
          */
        virtual wxString CreateUniqueFilename();

        /**
         * 通知编辑器我们正要创建上下文菜单.
         * 默认实现,只返回true.
         * 参数说明: position 指定弹出菜单的位置.
         * 参数说明: type 指定"模块类型(ModuleType)"弹出菜单.
         * 返回值:  如果编辑器返回false,则中止上下文菜单创建.
          */
        virtual bool OnBeforeBuildContextMenu(cb_optional const wxPoint& position, cb_optional ModuleType type){ return true; }

        /**
         * 通知编辑器我们已经完成上下文菜单的创建(即将显示).
         * 默认实现什么也不做.
         * 参数说明: type 指定"模块类型(ModuleType)"上下文弹出菜单.
        */
        virtual void OnAfterBuildContextMenu(cb_optional ModuleType type){}

        /*不要干涉它(是内置编辑器)!*/
        bool m_IsBuiltinEditor;
        wxString m_Shortname;
        wxString m_Filename;
        /*使用此选项添加新的变量/函数,不破坏ABI(应用程序二进制接口(Application Binary Interface))*/
        EditorBaseInternalData* m_pData;
    private:
        /*防止复制构造*/
        EditorBase(cb_unused const EditorBase& rhs);
        /*所有弹出菜单项的一个事件处理程序*/
        void OnContextMenuEntry(wxCommandEvent& event);
        //pecan 2006/03/22
        void BasicAddToContextMenu(wxMenu* popup, ModuleType type);
        SwitchToMap m_SwitchTo;
        wxString m_WinTitle;
        wxString lastWord;
};

#endif // EDITORBASE_H
